Giải thích về vdev, Storage vdev và Support vdev là gì
Hệ thống tập tin ZFS (Zettabyte File System), các thuật ngữ như vdev, Storage vdev và Support vdev đóng vai trò quan trọng trong việc quản lý và tổ chức dữ liệu. Để hiểu rõ hơn về cách ZFS quản lý lưu trữ, chúng ta cần tìm hiểu về các khái niệm này và cách chúng tương tác với nhau.
Zpool là tập hợp của nhiều vdev
Biểu đồ trên cho chúng ta thấy một hồ bơi sử dụng bốn RAIDz2 vdevs và một của mỗi loại vdev hỗ trợ hiện đang được hỗ trợ.
Bắt đầu từ phía trên cùng, zpool là cấu trúc ZFS cấp cao nhất. Về mặt cấu trúc, một zpool là một bộ sưu tập của một hoặc nhiều storage vdevs và không hoặc nhiều vdevs hỗ trợ. Về mặt tiện ích, một zpool là một đối tượng lưu trữ có thể được chia thành các tập tin dữ liệu (trông giống như các thư mục) và zvols (trông giống như các thiết bị khối/ký tự đơn giản, như ổ đĩa thô).
Lưu ý rằng một zpool không chứa trực tiếp các ổ đĩa thực sự (hoặc các thiết bị khối/ký tự khác, như các tệp tin thưa thớt)! Đó là công việc của đối tượng tiếp theo bên dưới, vdev. Viết tắt của thiết bị ảo, mỗi vdev — dù là hỗ trợ hoặc lưu trữ — là một bộ sưu tập các thiết bị khối hoặc ký tự (đa số là ổ đĩa hoặc SSD) được sắp xếp theo một topology cụ thể.
Storage vdev là gì?
Một storage vdev có thể có topology là single, mirror, RAIDz1/2/3 hoặc DRAID. Ba topology đầu tiên khá đơn giản—nhưng DRAID lại là một loại riêng biệt, chúng ta sẽ bàn về nó trong phần riêng sau đây.
Single: loại vdev đơn giản nhất chứa một ổ đĩa duy nhất. Không có khả năng chống lỗi gần như nào ở đây (các khối metadata được lưu trữ làm sao đó, nhưng điều này sẽ không bảo vệ bạn khỏi một sự cố hoàn toàn với ổ đĩa). Đây là loại vdev nhanh nhất tuyệt đối cho một số lượng ổ đĩa nhất định, nhưng bạn nên sắp xếp sao lưu của mình một cách cẩn thận!
Mirror: loại vdev đơn giản này là loại có khả năng chống lỗi nhanh nhất. Mirrors thường được thấy trong các cấu hình hai ổ đĩa, nhưng cũng hỗ trợ số lượng lớn hơn. Trong một vdev mirror, tất cả các thiết bị thành viên đều có bản sao đầy đủ của tất cả dữ liệu được ghi vào vdev đó. Việc đọc có thể diễn ra với tốc độ lên đến n lần nhanh hơn so với một ổ đĩa đơn, nơi n là số ổ đĩa trong vdev, nhưng việc ghi bị hạn chế chậm hơn một chút so với một ổ đĩa đơn, bất kể có bao nhiêu ổ đĩa trong vdev.
RAIDz1: một vdev striped parity này giống với RAID5 cổ điển: dữ liệu được chia nhỏ đều qua tất cả các ổ đĩa trong vdev, với một ổ đĩa mỗi hàng được dành cho parity. Trong RAID5 cổ điển, parity được "rải rác" để nó không luôn rơi vào cùng một ổ đĩa, điều này cải thiện hiệu suất trong quá trình hỏng hóc và tái tạo. RAIDz1 thay vào đó phụ thuộc vào độ rộng dải động của nó để làm đổi khác: khác với RAID5 cổ điển, RAIDz1 có thể ghi một lượng nhỏ dữ liệu trong các dải hẹp. Vì vậy, một khối metadata, mà là một sector duy nhất rộng, sẽ được lưu trữ như một khối dữ liệu duy nhất và một khối parity duy nhất, ngay cả trên một vdev RAIDz1 rộng hơn nhiều—điều này không chỉ tiết kiệm không gian và tăng hiệu suất, mà còn phân phối parity một cách hiệu quả trên tất cả các ổ đĩa trong vdev, thay vì luôn lưu nó vào cùng một ổ đĩa trên mỗi dải được ghi.
RAIDz2: vdev striped parity thứ hai (và phổ biến nhất) của ZFS hoạt động giống như RAIDz1, nhưng với dual parity thay vì single parity. Trong trường hợp này, một khối metadata sẽ được ghi vào ba ổ đĩa, không phải hai: một ổ đĩa nhận dữ liệu gốc và hai ổ đĩa khác nhận các khối parity. Trong khi vdev RAIDz1 có thể mất một ổ đĩa mà không gây ra sự cố hoàn toàn, vdev RAIDz2 có thể mất hai ổ đĩa.
RAIDz3: topology striped parity cuối cùng này sử dụng triple parity, có nghĩa là nó có thể sống sót sau ba sự mất mát ổ đĩa mà không gây ra sự cố hoàn toàn—và cũng có nghĩa là metadata và các khối nhỏ khác được ghi vào tổng cộng bốn ổ đĩa (một dữ liệu và ba parity).
Support vdev là gì?
Bây giờ chúng ta đã biết về các topology của storage vdev, hãy nói về các lớp vdev. ("Lớp vdev" và "vdev hỗ trợ" không phải là thuật ngữ chính thức của ZFS, nhưng chúng cung cấp một cách tiện lợi để phân loại và hiểu cách ZFS quản lý bộ nhớ!)
Các loại vdev hỗ trợ hiện đang được triển khai bao gồm LOG, CACHE, SPECIAL và SPARE:
LOG: Bắt đầu bằng cách làm sáng tỏ một hiểu lầm phổ biến: LOG vdevs không phải là bộ đệm ghi hoặc đệm. Trong hoạt động bình thường, ZFS lưu các ghi đồng bộ vào đĩa hai lần: một lần, ngay lập tức, vào ZFS Intent Log và sau đó, tại một thời điểm nào đó sau đó, vào bộ nhớ chính. Trong trường hợp không có LOG vdev, cả hai ghi này sẽ vào các vdev lưu trữ chính.
Mặc dù việc ghi kép này cải thiện thông lượng ghi đồng bộ chủ yếu bằng cách giảm thiểu độ trễ thông qua việc sử dụng các khối ZIL được cấp phát trước, tránh mất thời gian để tìm vị trí để đặt dữ liệu và giảm thiểu sự phân mảnh và do đó giảm độ trễ tìm kiếm. Một LOG vdev đơn giản là một nơi để lưu trữ ZIL mà không phải là lưu trữ chính: không nhiều hơn, không ít hơn.
Thông thường, LOG vdev là một thiết bị có độ trễ rất thấp, vì vậy việc đồng bộ dữ liệu đến nó sẽ nhanh hơn đáng kể so với lưu trữ chính, đó là lý do tại sao lớp vdev LOG tồn tại. Các ghi vào LOG không bao giờ được đọc lại trừ khi có một sự cố hệ thống hoặc kernel, đó là lý do tại sao LOG không nên được coi là một "bộ đệm ghi!"
Một LOG có thể sử dụng topology single hoặc mirror (bất kỳ kích thước nào); nó không thể sử dụng RAIDz hoặc DRAID. Bạn có thể có bất kỳ LOG vdev nào mà bạn muốn, nếu bạn có quá nhiều ghi đồng bộ mà bạn muốn phân phối tải trên nhiều LOG!
CACHE: theo một nghĩa nào đó, CACHE vdev (còn được gọi là L2ARC) dễ hiểu hơn: nó thực sự chỉ là một bộ đệm đọc. Thật không may, nó thực sự không phải là ARC—Adaptive Replacement Cache. L2ARC là một bộ đệm vòng LILO đơn giản, không phải từ các khối đã hết hạn khỏi ARC, mà từ các khối có thể sớm hết hạn.
CACHE vdev có một bộ đệm ghi giới hạn khá thấp để ngăn nó tiêu thụ SSD như một cây hàn cắt qua giấy vệ sinh, điều này cũng đồng nghĩa với khả năng có một khối cụ thể mà bạn đã đọc có sẵn thấp hơn bạn có thể mong đợi.
Kết hợp với tỉ lệ trúng cao cực kỳ trong ARC chính, và CACHE vdevs thường không nhận được nhiều hit cho đa số công việc làm. CACHE vdev sẽ không bao giờ có tỉ lệ trúng cao, vì một khi có một hit, khối đó sẽ được chuyển lại vào ARC chính.
Mất một CACHE vdev không ảnh hưởng tiêu cực đến pool, ngoại trừ việc mất bất kỳ tăng tốc nào có thể đã được đạt được từ CACHE.
Tính năng CACHE chỉ hỗ trợ topology đơn-ổ đĩa. Vì CACHE không bao giờ lưu trữ bản sao dữ liệu duy nhất, và việc mất CACHE sẽ không ảnh hưởng đến pool, vì vậy không có lý do nào để hỗ trợ bất kỳ topology nào ngoài topology nhanh nhất và đơn giản nhất. (Lưu ý: Bạn hoàn toàn có thể có nhiều hơn một CACHE vdev nếu bạn muốn, để phân phối tải trên nhiều hơn một ổ đĩa.)
SPECIAL: Lớp vdev SPECIAL là lớp hỗ trợ mới nhất, được giới thiệu để cân bằng nhược điểm của các vdev DRAID (chúng ta sẽ bàn sau). Khi bạn đính kèm một SPECIAL vào một pool, tất cả các ghi metadata trong tương lai cho pool đó sẽ được đưa vào SPECIAL, không phải vào bộ nhớ chính.
Tùy chọn, SPECIAL cũng có thể được cấu hình để lưu trữ các khối dữ liệu nhỏ. Ví dụ, với special_small_blocks=4K, các tệp cá nhân 4KiB hoặc nhỏ hơn sẽ được lưu trữ hoàn toàn trên SPECIAL; với special_small_blocks=64K, các tệp 64KiB hoặc nhỏ hơn sẽ được lưu trữ hoàn toàn trên SPECIAL.
Thông số special_small_blocks có thể được thiết lập trên mỗi bộ dữ liệu. Bạn không thể loại bỏ việc lưu trữ các khối metadata vào SPECIAL: nếu bạn có một (hoặc nhiều), nó (hoặc chúng) sẽ nhận tất cả các ghi metadata của bạn, không có ngoại lệ.
Việc mất một SPECIAL vdev nào đó, giống như việc mất bất kỳ vdev lưu trữ nào khác, mất toàn bộ pool cùng với nó. Vì lý do này, SPECIAL phải là một topology có khả năng chống lỗi—và nó cần phải chống lỗi đúng như vdev lưu trữ của bạn. Vì vậy, một pool với lưu trữ RAIDz3 cần một SPECIAL được sao chép bốn lần—vdev lưu trữ của bạn có thể chịu được ba lỗi ổ đĩa, vì vậy SPECIAL của bạn cũng phải có thể chịu được ba lỗi ổ đĩa.
Giống như lớp vdev LOG, bạn có thể có bất kỳ SPECIAL vdev nào bạn muốn, nếu bạn cần phân phối tải trên nhiều ổ đĩa hơn. Tuy nhiên, khác với LOG, mất một SPECIAL nào đó mất hết pool còn lại cùng với nó mà không thể phục hồi được!
SPARE: Lớp vdev SPARE không làm gì cả trong quá trình hoạt động bình thường, nhưng sẵn sàng được tự động phục hồi vào bất kỳ vdev nào mà một ổ đĩa bị lỗi. Rõ ràng, một SPARE phải có ít nhất kích thước của một ổ đĩa bị lỗi để tự động thay thế ổ đĩa đó!
Nếu pool của bạn chỉ có một vdev lưu trữ duy nhất, nó không cần SPAREs. Ích lợi của một SPARE là nó có thể phục vụ bất kỳ vdev nào trong pool mà trở nên bị lỗi. Trong một pool có một vdev duy nhất, việc điều chỉnh định mức cân bằng làm tốt hơn là triển khai SPAREs—ví dụ, trong một hệ thống có mười hai ổ đĩa, một vdev RAIDz3 rộng mười một sẽ hoạt động hiệu quả hơn so với một vdev RAIDz2 rộng mười cộng với một SPARE.
Chỉ số quan trọng cho thấy bạn có thể cần các vdev SPARE là số lượng vdev lưu trữ, không phải số lượng ổ đĩa lưu trữ. Nếu bạn có sáu hoặc nhiều vdev, bạn hầu như chắc chắn nên duy trì một hoặc nhiều SPAREs—và không quan trọng nếu sáu vdev đó là gương hai ổ đĩa (tổng cộng mười hai ổ đĩa) hoặc RAIDz2 rộng mười (tổng cộng sáu mươi ổ đĩa); dù sao đi nữa, bạn thực sự muốn cửa sổ dễ tổn thương hơn mà SPARE cung cấp khi một trong các vdev của bạn trở nên bị lỗi!
Loại vdev mới nhất của ZFS: DRAID
Chúng ta đã đề cập đến DRAID một vài lần ở trên, nhưng rất khó để giải thích một cách đúng đắn mà không hiểu được cái gì đến trước đó — vì vậy, bây giờ khi chúng ta đã đi qua các topology vdev tiêu chuẩn và các loại vdev hỗ trợ (đặc biệt là SPARE), hãy nói về DRAID.
Topology này được thiết kế cho các hệ thống có 60 ổ hoặc nhiều hơn, và thay thế một nhóm truyền thống của lưu trữ và SPARE vdevs bằng một vdev lớn đơn, bao gồm cả chức năng RAIDz và SPARE.
Hãy nói rằng bạn có đúng sáu mươi ổ cứng, và bạn muốn sử dụng chúng trong một DRAID. Bước đầu tiên của bạn là quyết định chiều rộng gạch và cấp độ dư thừa... điều này, khác với RAIDz, không bị ràng buộc chặt chẽ bởi số lượng ổ đĩa bạn có sẵn.
Trước khi có DRAID, bạn có thể đã quyết định rằng sáu mươi ổ cứng của bạn nên là chín vdevs RAIDz2 với chiều rộng sáu đĩa và sáu vdevs SPARE. Ngay khi bạn quyết định chiều rộng và cấp độ dư thừa của vdevs của mình, số lượng vdevs trở nên cố định: về cơ bản, bạn không thể đặt nhiều hơn mười vdevs sáu đĩa trên tổng số sáu mươi ổ cứng.
Tuy nhiên, DRAID cung cấp tính linh hoạt hơn: trong khi bạn chắc chắn có thể chọn một DRAID2:4:4 (mỗi gạch có 2 khối dư thừa và bốn khối dữ liệu, và DRAID như một tổng thể cung cấp khả năng dư thừa phân tán tương đương với 4 ổ đĩa), bạn cũng có thể chọn một DRAID3:4:4.
Rõ ràng, ba khối dư thừa và bốn khối dữ liệu mỗi gạch không cộng lại thành một số chia hết cho chính xác số sáu mươi ổ đĩa của bạn... nhưng điều đó không cần thiết, vì DRAID sẽ vui vẻ "bọc" một gạch khi và nếu cần thiết để làm cho nó phù hợp với ma trận các ổ đĩa bạn có.
Có một quỷ đỏ trong những chi tiết đó: tạo ra một chiều rộng gạch DRAID không chia hết cho số lượng ổ đĩa bạn có có thể gây ra một hình phạt về hiệu suất. Nhưng khi bạn có 60 ổ đĩa trở lên, loại vấn đề hiệu suất đó thường tan biến: điểm hạn chế trên một hệ thống 60 ổ đĩa thường là chính các bộ điều khiển ổ đĩa, không phải là các ổ đĩa cá nhân.
Trong một cấu hình DRAID, thay vì một ổ đĩa cụ thể được ánh xạ vào một gạch nhất định trong một RAIDz cụ thể, mỗi thành viên của vdev DRAID được phân phối trên tất cả 60 ổ đĩa trong vdev. Khi một ổ đĩa gặp sự cố, thay vì mất một gạch hoàn toàn, thay vào đó mất là 1/60 của mỗi trong số 60 thành viên.
Nếu một ổ đĩa gặp sự cố trong vdev DRAID của chúng ta, các khối dữ liệu thuộc về ổ đĩa bị lỗi sẽ được tái tạo từ dư thừa và được resilver vào dung lượng dư thừa phân tán bên trong DRAID. Quá trình resilver này diễn ra nhanh hơn nhiều so với một quá trình resilver truyền thống vào một vdev SPARE.
Để so sánh, hãy xem xét ví dụ trước đó của chúng tôi, sáu vdev RAIDZ2s có chiều rộng chín ổ đĩa và sáu dự phòng. Khi một ổ đĩa gặp sự cố, chúng tôi sẽ đọc từ tám ổ đĩa còn lại và ghi vào một dự phòng duy nhất.
Trong khi đó, với DRAID, vì hạn chế lớn nhất của một quá trình resilver truyền thống — tốc độ ghi — bây giờ được phân phối qua tất cả năm mươi chín ổ đĩa còn lại, không chỉ là một ổ đĩa duy nhất! Chúng tôi kết thúc việc đọc từ năm mươi chín ổ đĩa và ghi vào năm mươi chín ổ đĩa, điều này rõ ràng sẽ hoàn thành nhanh hơn nhiều so với tám và một trong một RAIDz truyền thống.
Thật không may, để thu hồi lại dung lượng dư thừa phân tán đã sử dụng, người vận hành của vdev DRAID vẫn phải thực hiện một quá trình resilvering truyền thống của một ổ đĩa mới vào DRAID, và quá trình resilver này sẽ chậm chạp như bất kỳ quá trình resilver truyền thống nào khác.
Tuy nhiên, có một cửa sổ tổn thất cho quá trình resilvering đầu tiên (vì DRAID thiếu một cấp độ dư thừa) và không có cửa sổ tổn thất cho quá trình thứ hai (vì cấp độ dư thừa bị thiếu đã được khôi phục bằng cách sử dụng dung lượng dư thừa phân tán).
Tuy nhiên, vdev DRAID cũng đi kèm với những hạn chế — hạn chế lớn nhất là chúng mất khả năng của vdev RAIDz truyền thống trong việc lưu trữ dữ liệu trong các chiều rộng gạch động. Nếu bạn có một DRAID2:4:4, mỗi gạch phải có chiều rộng sáu ổ đĩa (bốn dữ liệu cộng với hai dư thừa), ngay cả khi gạch đó chỉ lưu trữ một khối dữ liệu siêu nhỏ 4KiB.
Đây là nơi mà vdev SPECIAL có thể hữu ích — trong khi một SPECIAL có thể là một điều tốt khi có trên một pool truyền thống, nó là một sự cần thiết gần như tuyệt đối trên một pool với một vdev DRAID rộng. Đặt metadata (và, tùy chọn, các khối dữ liệu rất nhỏ khác) trên SPECIAL có nghĩa là không cần phải lãng phí số lượng lớn không gian đĩa và hiệu suất để lưu trữ chúng một cách lãng phí trong các gạch có chiều rộng đầy đủ!
Như vậy, qua bài viết này, chúng ta đã có cái nhìn tổng quan về các khái niệm vdev, Storage vdev và Support vdev trong hệ thống tập tin ZFS. Tính linh hoạt và khả năng mở rộng của ZFS cho phép người quản trị hệ thống tùy chỉnh và tối ưu hóa việc quản lý lưu trữ theo nhu cầu cụ thể của họ. Hi vọng rằng thông tin này sẽ giúp bạn hiểu rõ hơn về cách ZFS hoạt động và cách tận dụng tối đa tiềm năng của nó trong môi trường lưu trữ của bạn.